home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / language / iconv8_s.arc / ICONT.ARC / TCODE.C < prev    next >
C/C++ Source or Header  |  1990-03-28  |  25KB  |  1,075 lines

  1. /*
  2.  * tcode.c -- translator functions for traversing parse trees and generating
  3.  *  code.
  4.  */
  5.  
  6. #include "..\h\config.h"
  7. #include "general.h"
  8. #include "tproto.h"
  9. #include "globals.h"
  10. #include "trans.h"
  11. #include "token.h"
  12. #include "tree.h"
  13. #include "tsym.h"
  14.  
  15. /*
  16.  * Prototypes.
  17.  */
  18.  
  19. hidden int    alclab        Params((int n));
  20. hidden novalue    binop        Params((int op));
  21. hidden novalue    emit        Params((char *s));
  22. hidden novalue    emitl        Params((char *s,int a));
  23. hidden novalue    emitlab        Params((int l));
  24. hidden novalue    emitn        Params((char *s,int a));
  25. hidden novalue    emits        Params((char *s,char *a));
  26. hidden novalue    setloc        Params((nodeptr n));
  27. hidden int    traverse    Params((nodeptr t));
  28. hidden novalue    unopa        Params((int op, nodeptr t));
  29. hidden novalue    unopb        Params((int op));
  30.  
  31. extern int tfatals;
  32. extern int nocode;
  33. extern char *comfile;
  34.  
  35. /*
  36.  * Code generator parameters.
  37.  */
  38.  
  39. #define LoopDepth   20        /* max. depth of nested loops */
  40. #define CaseDepth   10        /* max. depth of nested case statements */
  41. #define CreatDepth  10        /* max. depth of nested create statements */
  42.  
  43. /*
  44.  * loopstk structures hold information about nested loops.
  45.  */
  46. struct loopstk {
  47.    int nextlab;            /* label for next exit */
  48.    int breaklab;        /* label for break exit */
  49.    int markcount;        /* number of marks */
  50.    int ltype;            /* loop type */
  51.    };
  52.  
  53. /*
  54.  * casestk structure hold information about case statements.
  55.  */
  56. struct casestk {
  57.    int endlab;            /* label for exit from case statement */
  58.    nodeptr deftree;        /* pointer to tree for default clause */
  59.    };
  60.  
  61. /*
  62.  * creatstk structures hold information about create statements.
  63.  */
  64. struct creatstk {
  65.    int nextlab;            /* previous value of nextlab */
  66.    int breaklab;        /* previous value of breaklab */
  67.    };
  68. static int nextlab;        /* next label allocated by alclab() */
  69.  
  70. /*
  71.  * codegen - traverse tree t, generating code.
  72.  */
  73.  
  74. novalue codegen(t)
  75. nodeptr t;
  76.    {
  77.    nextlab = 1;
  78.    traverse(t);
  79.    }
  80.  
  81. /*
  82.  * traverse - traverse tree rooted at t and generate code.  This is just
  83.  *  plug and chug code for each of the node types.
  84.  */
  85.  
  86. static int traverse(t)
  87. register nodeptr t;
  88.    {
  89.    register int lab, n, i;
  90.    struct loopstk loopsave;
  91.    static struct loopstk loopstk[LoopDepth];    /* loop stack */
  92.    static struct loopstk *loopsp;
  93.    static struct casestk casestk[CaseDepth];    /* case stack */
  94.    static struct casestk *casesp;
  95.    static struct creatstk creatstk[CreatDepth]; /* create stack */
  96.    static struct creatstk *creatsp;
  97.  
  98.    n = 1;
  99.    switch (TType(t)) {
  100.  
  101.       case N_Activat:            /* co-expression activation */
  102.      if (Val0(Tree0(t)) == AUGACT) {
  103.         emit("pnull");
  104.         }
  105.      traverse(Tree2(t));        /* evaluate result expression */
  106.      if (Val0(Tree0(t)) == AUGACT)
  107.         emit("sdup");
  108.      traverse(Tree1(t));        /* evaluate activate expression */
  109.      setloc(t);
  110.      emit("coact");
  111.      if (Val0(Tree0(t)) == AUGACT)
  112.         emit("asgn");
  113.      break;
  114.  
  115.       case N_Alt:            /* alternation */
  116.      lab = alclab(2);
  117.      emitl("mark", lab);
  118.      loopsp->markcount++;
  119.      traverse(Tree0(t));        /* evaluate first alternative */
  120.      loopsp->markcount--;
  121.      emit("esusp");                 /*  and suspend with its result */
  122.      emitl("goto", lab+1);
  123.      emitlab(lab);
  124.      traverse(Tree1(t));        /* evaluate second alternative */
  125.      emitlab(lab+1);
  126.      break;
  127.  
  128.       case N_Augop:            /* augmented assignment */
  129.       case N_Binop:            /*  or a binary operator */
  130.      emit("pnull");
  131.      traverse(Tree1(t));
  132.      if (TType(t) == N_Augop)
  133.         emit("dup");
  134.      traverse(Tree2(t));
  135.      setloc(t);
  136.      binop((int)Val0(Tree0(t)));
  137.      break;
  138.  
  139.       case N_Bar:            /* repeated alternation */
  140.      lab = alclab(1);
  141.      emitlab(lab);
  142.      emit("mark0");         /* fail if expr fails first time */
  143.      loopsp->markcount++;
  144.      traverse(Tree0(t));        /* evaluate first alternative */
  145.      loopsp->markcount--;
  146.      emitl("chfail", lab);          /* change to loop on failure */
  147.      emit("esusp");                 /* suspend result */
  148.      break;
  149.  
  150.       case N_Break:            /* break expression */
  151.      if (loopsp->breaklab <= 0)
  152.         nfatal(t, "invalid context for break");
  153.      else {
  154.         for (i = 0; i < loopsp->markcount; i++)
  155.            emit("unmark");
  156.         loopsave = *loopsp--;
  157.         traverse(Tree0(t));
  158.         *++loopsp = loopsave;
  159.         emitl("goto", loopsp->breaklab);
  160.         }
  161.      break;
  162.  
  163.       case N_Case:            /* case expression */
  164.      lab = alclab(1);
  165.      casesp++;
  166.      casesp->endlab = lab;
  167.      casesp->deftree = NULL;
  168.      emit("mark0");
  169.      loopsp->markcount++;
  170.      traverse(Tree0(t));        /* evaluate control expression */
  171.      loopsp->markcount--;
  172.      emit("eret");
  173.      traverse(Tree1(t));        /* do rest of case (CLIST) */
  174.      if (casesp->deftree != NULL) { /* evaluate default clause */
  175.         emit("pop");
  176.         traverse(casesp->deftree);
  177.         }
  178.      else
  179.         emit("efail");
  180.      emitlab(lab);            /* end label */
  181.      casesp--;
  182.      break;
  183.  
  184.       case N_Ccls:            /* case expression clause */
  185.      if (TType(Tree0(t)) == N_Res && /* default clause */
  186.          Val0(Tree0(t)) == DEFAULT) {
  187.         if (casesp->deftree != NULL)
  188.            nfatal(t, "more than one default clause");
  189.         else
  190.            casesp->deftree = Tree1(t);
  191.         }
  192.      else {                /* case clause */
  193.         lab = alclab(1);
  194.         emitl("mark", lab);
  195.         loopsp->markcount++;
  196.         emit("ccase");
  197.         traverse(Tree0(t));        /* evaluate selector */
  198.         setloc(t);
  199.         emit("eqv");
  200.         loopsp->markcount--;
  201.         emit("unmark");
  202.         emit("pop");
  203.         traverse(Tree1(t));        /* evaluate expression */
  204.         emitl("goto", casesp->endlab); /* goto end label */
  205.         emitlab(lab);        /* label for next clause */
  206.         }
  207.      break;
  208.  
  209.       case N_Clist:            /* list of case clauses */
  210.      traverse(Tree0(t));
  211.      traverse(Tree1(t));
  212.      break;
  213.  
  214.       case N_Conj:            /* conjunction */
  215.      if (Val0(Tree0(t)) == AUGAND) {
  216.         emit("pnull");
  217.         }
  218.      traverse(Tree1(t));
  219.      if (Val0(Tree0(t)) != AUGAND)
  220.         emit("pop");
  221.      traverse(Tree2(t));
  222.      if (Val0(Tree0(t)) == AUGAND) {
  223.         setloc(t);
  224.         emit("asgn");
  225.         }
  226.      break;
  227.  
  228.       case N_Create:            /* create expression */
  229.      creatsp++;
  230.      creatsp->nextlab = loopsp->nextlab;
  231.      creatsp->breaklab = loopsp->breaklab;
  232.      loopsp->nextlab = 0;        /* make break and next illegal */
  233.      loopsp->breaklab = 0;
  234.      lab = alclab(3);
  235.      emitl("goto", lab+2);          /* skip over code for co-expression */
  236.      emitlab(lab);            /* entry point */
  237.      emit("pop");                   /* pop the result from activation */
  238.      emitl("mark", lab+1);
  239.      loopsp->markcount++;
  240.      traverse(Tree0(t));        /* traverse code for co-expression */
  241.      loopsp->markcount--;
  242.      setloc(t);
  243.      emit("coret");                 /* return to activator */
  244.      emit("efail");                 /* drive co-expression */
  245.      emitlab(lab+1);        /* loop on exhaustion */
  246.      emit("cofail");                /* and fail each time */
  247.      emitl("goto", lab+1);
  248.      emitlab(lab+2);
  249.      emitl("create", lab);          /* create entry block */
  250.      loopsp->nextlab = creatsp->nextlab;   /* legalize break and next */
  251.      loopsp->breaklab = creatsp->breaklab;
  252.      creatsp--;
  253.      break;
  254.  
  255.       case N_Cset:            /* cset literal */
  256.      emitn("cset", (int)Val0(t));
  257.      break;
  258.  
  259.       case N_Elist:            /* expression list */
  260.      n = traverse(Tree0(t));
  261.      n += traverse(Tree1(t));
  262.      break;
  263.  
  264.       case N_Empty:            /* a missing expression */
  265.      emit("pnull");
  266.      break;
  267.  
  268.       case N_Field:            /* field reference */
  269.      emit("pnull");
  270.      traverse(Tree0(t));
  271.      setloc(t);
  272.      emits("field", Str0(Tree1(t)));
  273.      break;
  274.  
  275.  
  276.       case N_Id:            /* identifier */
  277.      emitn("var", (int)Val0(t));
  278.      break;
  279.  
  280.       case N_If:            /* if expression */
  281.      if (TType(Tree2(t)) == N_Empty) {
  282.         lab = 0;
  283.         emit("mark0");
  284.         }
  285.      else {
  286.         lab = alclab(2);
  287.         emitl("mark", lab);
  288.         }
  289.      loopsp->markcount++;
  290.      traverse(Tree0(t));
  291.      loopsp->markcount--;
  292.      emit("unmark");
  293.      traverse(Tree1(t));
  294.      if (lab > 0) {
  295.         emitl("goto", lab+1);
  296.         emitlab(lab);
  297.         traverse(Tree2(t));
  298.         emitlab(lab+1);
  299.         }
  300.      break;
  301.  
  302.       case N_Int:            /* integer literal */
  303.      emitn("int", (int)Val0(t));
  304.      break;
  305.  
  306.  
  307.       case N_Apply:            /* application */
  308.          traverse(Tree0(t));
  309.          traverse(Tree1(